﻿namespace TestApp
{
    using System;
    using System.Collections.Generic;
    using System.IO.IsolatedStorage;

    internal static class TypeExtensions
    {
        internal static StorageType TypeOf(this Type type)
        {
            switch (type.FullName)
            {
                case "System.Boolean":
                case "System.Byte":
                case "System.DateTime":
                case "System.Decimal":
                case "System.Double":
                case "System.Single":
                case "System.Guid":
                case "System.Int16":
                case "System.Int32":
                case "System.Int64":
                case "System.String":
                    return StorageType.String;
                case "System.Byte[]":
                    return StorageType.Binary;
                default:
                    return StorageType.Json;
            }
        }
    }

    public sealed class Storage
    {
        static Dictionary<StorageType, IStorage> storages;

        static Storage()
        {
            storages = new Dictionary<StorageType, IStorage>();

            storages.Add(StorageType.Json, new JsonStorage());
            storages.Add(StorageType.String, new StringStorage());
            storages.Add(StorageType.Binary, new BinaryStorage());
        }

        public static T Restore<T>(string key = null)
        {
            StorageType type = typeof(T).TypeOf();

            if (string.IsNullOrEmpty(key))
            {
                return storages[type].ReadFromType<T>();
            }

            return storages[type].ReadFromKey<T>(key);
        }

        public static void Store<T>(T obj, string key = null)
        {
            StorageType type = typeof(T).TypeOf();

            if (string.IsNullOrEmpty(key))
            {
                storages[type].WriteWithType(obj);
            }
            else
            {
                storages[type].WriteWithKey(obj, key);
            }
        }

        public static void Destroy(string key)
        {
            var storage = IsolatedStorageFile.GetUserStoreForApplication();
            if (storage.FileExists(key))
            {
                try
                {
                    storage.DeleteFile(key);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                }
            }
        }

        private Storage() { }
    }
}
